home *** CD-ROM | disk | FTP | other *** search
- ; []--------------------------------------------------[]
- ; | dpani.asm |
- ; | |
- ; | Deluxe Paint II Enhanced (v2.3) Animation TSR. |
- ; | |
- ; | Assemble with TASM 3.1 or greater. |
- ; | |
- ; | Copyright Carl Chimes 1993 |
- ; []--------------------------------------------------[]
-
- IDEAL
- MODEL TINY,C
-
- P8086
- SMART
- LOCALS
-
- ;----------------------------------------------------------
- ; IIF (Instruction IF) MACRO
- ;
- ; pre: cond = condition to execute instruc
- ; instruc = instruction to execute
- ; post: instruc executed if cond true, code continued
- ;----------------------------------------------------------
-
- MACRO IIF cond,instruc
- LOCAL cont1
-
- IFIDNI <cond>, <e>
- jne short cont1 ;; e -- ne
- ELSEIFIDNI <cond>, <z>
- jnz short cont1 ;; z -- nz
- ELSEIFIDNI <cond>, <ne>
- je short cont1 ;; ne -- e
- ELSEIFIDNI <cond>, <nz>
- jz short cont1 ;; nz -- z
- ELSEIFIDNI <cond>, <c>
- jnc short cont1 ;; c -- nc
- ELSEIFIDNI <cond>, <nc>
- jc short cont1 ;; nc -- c
- ELSEIFIDNI <cond>, <a>
- jbe short cont1 ;; a -- be
- ELSEIFIDNI <cond>, <b>
- jae short cont1 ;; b -- ae
- ELSEIFIDNI <cond>, <ae>
- jb short cont1 ;; ae -- b
- ELSEIFIDNI <cond>, <be>
- ja short cont1 ;; be -- a
- ELSEIFIDNI <cond>, <g>
- jle short cont1 ;; g -- le
- ELSEIFIDNI <cond>, <l>
- jge short cont1 ;; l - ge
- ELSEIFIDNI <cond>, <ge>
- jl short cont1 ;; ge -- l
- ELSEIFIDNI <cond>, <le>
- jg short cont1 ;; le -- g
- ELSEIFIDNI <cond>, <o>
- jno short cont1 ;; o -- no
- ELSEIFIDNI <cond>, <no>
- jo short cont1 ;; no -- o
- ELSEIFIDNI <cond>, <p>
- jnp short cont1 ;; p -- np
- ELSEIFIDNI <cond>, <pe>
- jnp short cont1 ;; pe -- np
- ELSEIFIDNI <cond>, <po>
- jp short cont1 ;; pe -- np
- ELSEIFIDNI <cond>, <np>
- jp short cont1 ;; np -- p
- ELSEIFIDNI <cond>, <s>
- jns short cont1 ;; s -- ns
- ELSEIFIDNI <cond>, <ns>
- js short cont1 ;; ns -- s
- ELSE
- ERR <Error in IIF>
- ENDIF
-
- instruc ;; execute instruc
- cont1:
- ENDM
-
-
-
- ;* initialised data *****************************************
- DATASEG
-
- ;* uninitialised data ***************************************
- UDATASEG
-
- ;* constants ************************************************
-
- MultiplexCode equ 0CCh ; the multiplex code
- MPRequestShutdown equ 01h ; function to request shutdown from Multiplex Int
- ; it restores all sw interrupts and returns
- ; paragraph address of TSR in ax
- BaseDPCodeSegConst equ 5AC6h
-
-
- ENUM AnimationTypes {
- AniTypeCycle=0 ; cycle animation
- AniTypeRamp ; ramp animation
- AniTypeCount ; nr of animation types
- }
-
-
- ; key scan codes
- Key_Alt_GREYENTER = 0a600h
- Key_GREYENTER = 0e00dh
- Key_F11 = 08500h
- Key_F12 = 08600h
- Key_Alt_W = 01100h
- Key_Alt_H = 02300h
- Key_Alt_M = 03200h
- Key_ESC = 0011bh
- Key_Alt_1 = 07800h
- Key_Alt_2 = 07900h
- Key_Alt_GREYLEFT = 09b00h
- Key_Alt_GREYRIGHT= 09d00h
- Key_Alt_GREYUP = 09800h
- Key_Alt_GREYDOWN = 0a000h
-
- ;
- ; Pre: dpseg!=ax and dpofs!=ax
- ;
- MACRO CallFar dpseg,dpofs
- push ax
- mov ax,[cs:BaseDPCodeSeg]
- add ax,dpseg
- sub ax,BaseDPCodeSegConst
- mov [WORD HIGH cs:tempAddr],ax
- mov ax,dpofs
- mov [WORD LOW cs:tempAddr],ax
- pop ax
- call [DWORD cs:tempAddr]
- ENDM
-
- ;* code *****************************************************
-
- CODESEG
-
- STARTUPCODE
- jmp InitAndTerminate
-
-
- ;* code data ************************************************
-
- startupKbVec dd ? ; startup keyboard int 16h
- startupMultiplexVec dd ? ; startup multiplex int 2fh
- startupTickerVec dd ? ; startup ticker int 08h
- runtimeDosVec dd ? ; runtime dos vector 21h
- dpRunning dw 0 ; whether dp is running
- BaseDPCodeSeg dw 0 ; the actual value of the base segment
- dsDPSeg dw 0 ; data segment of dp
- tempAddr dd ? ; temporary address
-
- ; animation variables
- aniOn dw 0 ; whether animation is on
- aniPixmapWidth dw 16 ; width of each pixmap in animation
- aniPixmapHeight dw 16 ; height of each pixmap in animation
- aniMultiWidth dw 1 ; nr of pixmaps width in multi-block frame
- aniMultiHeight dw 1 ; nr of pixmaps height in multi-block frame
- aniMultiOn dw 0 ; whether in multi-mode
- aniFirst dw 0 ; first pixmap in sequence
- aniLast dw 0 ; last pixmap in sequence
- aniQty dw 1 ; nr of pixmaps in sequence
- aniCur dw 0 ; current pixmap in sequence
- aniDirn dw 0 ; current animation direction (for ramp)
- aniType dw AniTypeCycle ; type of animation
- aniSpeedDelay dw 2 ; speed delay
- aniSpeedCount dw 0 ; speed count
- aniViewX dw 0 ; x coord at which to view current frame
- aniViewY dw -1 ; y coord at which to view current frame (-1 means at bottom of screen)
-
-
- ;------------------------------------------------------------
- ; dpCodeCheck is a byte pattern against which to compare
- ; calling code. If a match occurs assume calling code is
- ; Deluxe Paint II Enhanced v2.3.
- ; Note that other versions of Deluxe Paint are likely to
- ; have this code too so dpAni is likely to detect a bad
- ; version and think it's okay.
- ;------------------------------------------------------------
- dpCodeCheck:
- jz short @@5AC6_067B
- mov ax,0FFFFh
- retf
- @@5AC6_067B:
- xor ax,ax
- retf
- mov ah,0
- int 16h
- or al,al
- jz short @@5AC6_0688
- xor ah,ah
- @@5AC6_0688:
- retf
-
- dpCodeCheckLength = ((OFFSET $) - (OFFSET dpCodeCheck))
-
-
- ;* real code ************************************************
-
- ;------------------------------------------------------------
- ; myDosInt
- ;
- ; my dos int - used to trap exit in DP
- ;
- ;
- ;------------------------------------------------------------
- PROC myDosInt NEAR
-
- ASSUME ds:NOTHING, ss:NOTHING
-
- cmp ah,4Ch
- je @@detach
- cmp ah,00h
- je @@detach
-
- pushf
- call [DWORD cs:runtimeDosVec] ; simulate call to true dos vector
- retf 2 ; preserve flags
-
- @@detach:
- mov [dpRunning],0 ; dp no longer running
- mov [aniOn],0 ; no more animation
-
- push ax
- push bx
- push es
- sub bx,bx
- mov es,bx
- mov bx,21h*4
- mov ax,[WORD cs:runtimeDosVec]
- mov [WORD es:bx],ax
- mov ax,[WORD HIGH cs:runtimeDosVec]
- mov [WORD es:bx+2],ax ; restore runtime dos vector
- pop es
- pop bx
- pop ax
-
- pushf
- call [DWORD cs:runtimeDosVec] ; now do function
- retf 2 ; preserve flags
-
- ENDP myDosInt
-
-
- ;------------------------------------------------------------
- ; myKbInt
- ;
- ; My keyboard interrupt, patching int 16h
- ;
- ;
- ;------------------------------------------------------------
- PROC myKbInt NEAR
-
- ASSUME ds:NOTHING, ss:NOTHING
-
- push ax bx cx dx es
- call doDelayedAniStep
- pop es dx cx bx ax
-
- cmp ah,1
- je @@readchar
-
- pushf
- call [DWORD cs:startupKbVec] ; jmp to old int
- retf 2 ; must preserve flags
-
- @@readchar:
- mov ah,11h
- pushf
- call [DWORD cs:startupKbVec] ; do an extended read
- IIF z,<jmp @@returnread> ; no chars, return
-
- ; char is available - dispatch to my routines if is one of mine
-
- cmp ax,Key_F12
- IIF e,<jmp @@AttachToDP> ; attach to DP
-
- cmp [dpRunning],0
- IIF e,<jmp @@returnread> ; deluxe paint not running - do no functions
-
- cmp ax,Key_GREYENTER
- IIF e,<jmp @@SetFirstPixmap> ; set first endpoint of animation
- cmp ax,Key_Alt_GREYENTER
- IIF e,<jmp @@SetLastPixmap> ; set last endpoint of animation
- cmp ax,Key_F11
- IIF e,<jmp @@PauseContinue> ; pause/continue animation
- cmp ax,Key_Alt_GREYRIGHT
- IIF e,<jmp @@SingleStepFwd> ; single step of animation forwards
- cmp ax,Key_Alt_GREYLEFT
- IIF e,<jmp @@SingleStepRev> ; single step of animation reverse
- cmp ax,Key_Alt_GREYUP
- IIF e,<jmp @@SpeedIncrease> ; increase speed
- cmp ax,Key_Alt_GREYDOWN
- IIF e,<jmp @@SpeedDecrease> ; decrease speed
- cmp ax,Key_Alt_W
- IIF e,<jmp @@SetWidth> ; set width of pixmap
- cmp ax,Key_Alt_H
- IIF e,<jmp @@SetHeight> ; set height of pixmap
- cmp ax,Key_Alt_1
- IIF e,<jmp @@SetAniType1> ; set animation type 1
- cmp ax,Key_Alt_2
- IIF e,<jmp @@SetAniType2> ; set animation type 2
- cmp ax,Key_Alt_M
- IIF e,<jmp @@ToggleMulti> ; toggle multiblock sprites
- jmp @@returnread ; no function, behave normally
-
- @@SetFirstPixmap:
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; remove function invoking key from buffer
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; get pixmap number
- dec ax ; adjust since lowest enterable nr is 1
- push ax
- call clampPixmapNrToScreen ; put in legal range
- add sp,2
- mov [aniFirst],ax ; set aniFirst
- mov [aniCur],ax ; set current to new first
- add ax,[aniQty]
- dec ax ; new last
- push ax
- call clampPixmapNrToScreen ; put in legal range
- add sp,2
- mov [aniLast],ax ; store new last
- jmp @@readchar ; check next in buffer
-
- @@SetLastPixmap:
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; remove function invoking key from buffer
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; get nr of pixmaps in sequence
- mov [aniQty],ax
- add ax,[aniFirst]
- dec ax ; convert qty to last pixmap
- push ax
- call clampPixmapNrToScreen ; put in legal range
- add sp,2
- mov [aniLast],ax ; set aniLast
- mov ax,[aniFirst]
- mov [aniCur],ax ; new cur = first
- jmp @@readchar ; check next in buffer
-
- @@PauseContinue:
- xor [aniOn],1 ; toggle whether on (not-paused)
- jmp @@removeandtrynext ; check next in buffer
-
- @@SingleStepRev:
- push ax bx cx dx es
- call aniStepOnceRev
- pop es dx cx bx ax
- jmp @@removeandtrynext ; check next in buffer
-
- @@SingleStepFwd:
- push ax bx cx dx es
- call aniStepOnceFwd
- pop es dx cx bx ax
- jmp @@removeandtrynext ; check next in buffer
-
- @@SpeedIncrease: ; speed increase
- cmp [aniSpeedDelay],0
- je @@speedinccont ; if aniDelay>0
- dec [aniSpeedDelay] ; aniDelay--
- @@speedinccont:
- jmp @@removeandtrynext ; check next in buffer
-
- @@SpeedDecrease:
- cmp [aniSpeedDelay],0FFFFh
- je @@speeddeccont ; if aniDelay<0FFFFh
- inc [aniSpeedDelay] ; aniDelay++
- @@speeddeccont:
- jmp @@removeandtrynext ; check next in buffer
-
- @@SetWidth:
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; remove function invoking key from buffer
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; get width in pixels
- push ds
- mov ds,[cs:dsDPSeg]
- cmp ax,[WORD ds:98h] ; width of screen
- jle @@setwidcont1 ; if width>screenwidth
- mov ax,[WORD ds:98h] ; width=screenwidth
- @@setwidcont1:
- pop ds
- mov [aniPixmapWidth],ax ; store width
-
- mov ax,[aniFirst]
- call clampPixmapNrToScreen
- mov [aniFirst],ax ; make sure first pixmap nr on screen
- mov ax,[aniLast]
- call clampPixmapNrToScreen
- mov [aniLast],ax ; make sure last pixmap nr on screen
- mov ax,[aniCur]
- call clampPixmapNrToScreen
- mov [aniCur],ax ; make sure cur pixmap nr on screen
- jmp @@readchar ; try next in buffer
-
- @@SetHeight:
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; remove function invoking key from buffer
- mov ah,10h
- pushf
- call [DWORD cs:startupKbVec] ; get height in pixels
- push ds
- mov ds,[cs:dsDPSeg]
- cmp ax,[WORD ds:9Ah] ; height of screen
- jle @@sethgtcont1 ; if height>screenheight
- mov ax,[WORD ds:9Ah] ; height=screenheight
- @@sethgtcont1:
- pop ds
- mov [aniPixmapHeight],ax ; store height
-
- mov ax,[aniFirst]
- call clampPixmapNrToScreen
- mov [aniFirst],ax ; make sure first pixmap nr on screen
- mov ax,[aniLast]
- call clampPixmapNrToScreen
- mov [aniLast],ax ; make sure last pixmap nr on screen
- mov ax,[aniCur]
- call clampPixmapNrToScreen
- mov [aniCur],ax ; make sure cur pixmap nr on screen
- jmp @@readchar ; try next in buffer
-
- @@SetAniType1:
- mov [aniType],AniTypeCycle
- jmp @@removeandtrynext
-
- @@SetAniType2:
- mov [aniType],AniTypeRamp
- jmp @@removeandtrynext
-
- @@ToggleMulti: ; toggle multiblock sprite
- xor [aniMultiOn],1
- jz @@multioff
- ; turn multi on
- mov [aniMultiWidth],2 ; turn multi on
- mov [aniMultiHeight],2
- jmp @@multicont
- @@multioff: ; turn multi off
- mov [aniMultiWidth],1
- mov [aniMultiHeight],1
- @@multicont:
- jmp @@removeandtrynext
-
- @@AttachToDP: ; attach to DP
-
- ; check if already attached
- cmp [cs:dpRunning],0
- IIF ne,<jmp @@removeandtrynext> ; already (attached), check next in buffer
-
- ; check if DP is really running
- push bp
- mov bp,sp
- push cx
- push si
- push di
- push es
- push ds
- les di,[bp+2] ; esdi= calling code return addr
- push cs
- pop ds
- mov si,OFFSET dpCodeCheck ; dssi= code check start
- mov cx,dpCodeCheckLength
- repe cmpsb
- jne @@attachdetachend ; not a match - do nothing
-
- ; was a match - attach to DP
- mov [cs:dpRunning],1
-
- ; save segments
- mov [cs:BaseDPCodeSeg],es ; save base segment
- pop ds
- push ds ; ds= calling data segment
- mov [cs:dsDPSeg],ds ; store in dsDPSeg
-
- ; hook into Dos Int to catch when DP exits
- push ax
- push bx
- push es
- sub bx,bx
- mov es,bx
- mov bx,21h*4
- ; get runtime dos vector
- mov ax,[WORD es:bx]
- mov [WORD cs:runtimeDosVec],ax
- mov ax,[WORD es:bx+2]
- mov [WORD HIGH cs:runtimeDosVec],ax ; orig vector gotten
- ; install my dos vector
- mov ax,OFFSET myDosInt
- mov [WORD es:bx],ax
- mov [WORD es:bx+2],cs ; my dos vector installed
- pop es
- pop bx
- pop ax
-
- ; test code - signal readiness of dpAni
- mov di,0a000h
- mov es,di
- mov di,0
- add [WORD es:di],0101h
-
- @@attachdetachend:
- pop ds
- pop es
- pop di
- pop si
- pop cx
- pop bp ; restore regs used in attach
- jmp short @@removeandtrynext
-
- @@removeandtrynext:
- mov ah,10h ; wait key function
- pushf
- call [DWORD cs:startupKbVec] ; remove key from buffer
- jmp @@readchar
-
- @@returnread: ; now do a limited read
- mov ah,1
- pushf
- call [DWORD cs:startupKbVec] ; call old interrupt
- retf 2 ; must preserve flags
- ENDP myKbInt
-
-
- ;------------------------------------------------------------
- ; clampPixmapNrToScreen
- ;
- ; clamp pixmap nr (arg0) to valid screen range
- ;
- ;
- ;------------------------------------------------------------
- PROC clampPixmapNrToScreen NEAR
- ARG pixmapnr
- USES ax,bx,dx,ds
-
- ASSUME ds:NOTHING,ss:NOTHING
- mov ds,[dsDPSeg] ; set ds to deluxe paints data seg
-
- mov ax,[ds:98h]
- cwd ; dxax= width of screen
- div [aniPixmapWidth]
- mov bx,ax ; bx= nr pixmaps across screen
-
- mov ax,[ds:9Ah]
- cwd ; dxax= height of screen
- div [aniPixmapHeight] ; ax = nr pixmaps down screen
-
- mul bx
- mov bx,ax ; bx = max legal pixmap+1
-
- mov ax,[pixmapnr]
- cmp ax,0
- jge @@cont1 ; if (ax<0)
- sub ax,ax ; ax=0
- jmp @@return
- @@cont1:
- cmp ax,bx
- jl @@return ; if (ax>bx)
- mov ax,bx
- dec ax ; ax = bx-1
- @@return:
- ret
- ENDP clampPixmapNrToScreen
-
-
- ;------------------------------------------------------------
- ; showFrame
- ;
- ; Shows the current animation frame at (aniViewX,aniViewY)
- ; The current frame is aniCur, with dimension (aniPixmapWidth,aniPixmapHeight)
- ;
- ;------------------------------------------------------------
- PROC showFrame NEAR
- LOCAL ViewX,ViewY,ViewLeftX,PageLeftX,PageTopY
- USES ds
-
- ASSUME ds:NOTHING,ss:NOTHING
-
- mov ds,[dsDPSeg] ; set ds to deluxe paints data seg
-
- CallFar 045D8h,0AD8h ; hide mouse
-
-
- ; find actual view x (may be -ve aniViewX => dist from right)
- mov ax,[aniViewX]
- cmp ax,0
- jge @@contx
- inc ax
- add ax,[WORD ds:98h] ; width of screen
- mov bx,ax
- mov ax,[aniPixmapWidth]
- mul [aniMultiWidth]
- neg ax
- add ax,bx ; ax= aniViewX+1 + scrwidth - aniPixmapWidth*aniMultiWidth
- @@contx:
- mov [ViewLeftX],ax ; store actual view X
-
- ; find actual view y (may be -ve aniViewY => dist from bottom)
- mov ax,[aniViewY]
- cmp ax,0
- jge @@conty
- inc ax
- add ax,[WORD ds:9Ah] ; height of screen
- mov bx,ax
- mov ax,[aniPixmapHeight]
- mul [aniMultiHeight]
- neg ax
- add ax,bx ; ax = aniViewY+1 + scrheight - aniPixmapHeight*aniMultiHeight
- @@conty:
- mov [ViewY],ax ; store actual view X
-
-
- ; find coords of aniCur on page
- mov ax,[ds:98h]
- cwd ; dxax= width of screen
- div [aniPixmapWidth]
- mov bx,ax ; bx= nr pixmaps across screen
- mov ax,[aniCur]
- div bx ; ax=y block coord, dx=x block coord
- mov bx,dx
- mul [aniPixmapHeight]
- mov [PageTopY],ax ; [PageTopY]= pixheight*(cur/(scrwidth/pixwidth))
- mov ax,bx
- mul [aniPixmapWidth]
- mov [PageLeftX],ax ; [PageLeftX]= pixwidth*(cur%(scrwidth/pixwidth))
-
- mov cx,[aniMultiHeight]
- @@loopy:
- push cx
-
- mov ax,[ViewLeftX]
- mov [ViewX],ax ; ViewX= ViewLeftX
- mov cx,[aniMultiWidth]
- @@loopx:
- push cx
-
- sub ax,ax
- push ax ;+16=0
- push [aniPixmapHeight] ;+14= hgt of region on screen
- push [aniPixmapWidth] ;+12= wid of region on screen
- push [ViewY] ;+10=0 y top of region on screen
- push [ViewX] ;+0E=0 x left of region on screen
- mov ax,0B6C8h
- push ax
- push [PageTopY] ;+0A=0 start y coord on page
- push [PageLeftX] ;+8=0 start x coord on page
- mov ax,52h
- push ax ;+6=52h ptr
- CallFar 03cadh,00fah ; call DP's draw pixmap routine
- add sp,12h
-
- mov ax,[aniPixmapWidth]
- add [ViewX],ax ; ViewX += aniPixmapWidth
-
- pop cx
- loop @@loopx ; loop for all aniMultiWidth
-
- mov ax,[aniPixmapHeight]
- add [ViewY],ax ; ViewY += aniPixmapHeight
-
- pop cx
- loop @@loopy ; loop for all aniMultiHeight
-
- CallFar 045D8h,0A94h ; show mouse
-
- ret
- ENDP showFrame
-
-
- ;------------------------------------------------------------
- ; aniStepOnceFwd
- ;
- ; do one animation step forwards regardless of aniOn
- ;
- ;
- ;------------------------------------------------------------
- PROC aniStepOnceFwd
- ASSUME ds:NOTHING,ss:NOTHING
-
- mov ax,[aniFirst]
- cmp ax,[aniLast]
- jge @@showandreturn ; if (first>=last) return
-
- mov bx,[aniType]
- cmp bx,AniTypeCycle
- je @@cycle ; dispatch to cycle
- cmp bx,AniTypeRamp
- je @@ramp ; dispatch to ramp
- jmp @@return ; invalid anitype return
-
- @@cycle: ; cycle {
- inc [aniCur] ; cur++;
- mov ax,[aniCur]
- cmp ax,[aniLast]
- jle @@cycledone ; if cur>last
- mov ax,[aniFirst] ; {
- mov [aniCur],ax ; cur= first;
- @@cycledone: ; }
- jmp @@showandreturn ; return
-
- @@ramp:
- cmp [aniDirn],0
- jne @@rampgoingdown
-
- @@rampgoingup:
- inc [aniCur] ; aniCur++
- mov ax,[aniLast]
- cmp [aniCur],ax
- jle @@rampupcont ; if (cur>last)
- dec ax
- mov [aniCur],ax ; cur=last-1
- mov [aniDirn],1 ; dirn= down
- @@rampupcont:
- jmp @@showandreturn
-
- @@rampgoingdown:
- dec [aniCur] ; aniCur--
- mov ax,[aniFirst]
- cmp [aniCur],ax
- jge @@rampdowncont ; if (cur<first)
- inc ax
- mov [aniCur],ax ; cur= first+1
- mov [aniDirn],0 ; dirn= up
- @@rampdowncont:
- jmp @@showandreturn
-
- @@showandreturn:
- call showFrame ; show the current frame
- @@return:
- ret
- ENDP aniStepOnceFwd
-
-
- ;------------------------------------------------------------
- ; aniStepOnceRev
- ;
- ; do one animation step in reverse regardless of aniOn
- ;
- ;
- ;------------------------------------------------------------
- PROC aniStepOnceRev
- ASSUME ds:NOTHING,ss:NOTHING
-
- mov ax,[aniFirst]
- cmp ax,[aniLast]
- jge @@showandreturn ; if (first>=last) return
-
- mov bx,[aniType]
- cmp bx,AniTypeCycle
- je @@cycle ; dispatch to cycle
- cmp bx,AniTypeRamp
- je @@ramp ; dispatch to ramp
- jmp @@return ; invalid anitype return
-
- @@cycle: ; cycle {
- dec [aniCur] ; cur--;
- mov ax,[aniCur]
- cmp ax,[aniFirst]
- jge @@cycledone ; if cur<first
- mov ax,[aniLast] ; {
- mov [aniCur],ax ; cur= last;
- @@cycledone: ; }
- jmp @@showandreturn ; return
-
- @@ramp:
- cmp [aniDirn],1 ; if ! going down
- jne @@rampgoingdown ; do reverse of normal
-
- @@rampgoingup:
- inc [aniCur] ; aniCur++
- mov ax,[aniLast]
- cmp [aniCur],ax
- jle @@rampupcont ; if (cur>last)
- dec ax
- mov [aniCur],ax ; cur=last-1
- mov [aniDirn],0 ; dirn= up
- @@rampupcont:
- jmp @@showandreturn
-
- @@rampgoingdown:
- dec [aniCur] ; aniCur--
- mov ax,[aniFirst]
- cmp [aniCur],ax
- jge @@rampdowncont ; if (cur<first)
- inc ax
- mov [aniCur],ax ; cur= first+1
- mov [aniDirn],1 ; dirn= down
- @@rampdowncont:
- jmp @@showandreturn
- @@showandreturn:
- call showFrame ; show the current frame
- @@return:
- ret
- ENDP aniStepOnceRev
-
-
- ;------------------------------------------------------------
- ; doDelayedAniStep
- ;
- ; Does an animation step every aniDelay ticker ticks
- ;
- ;
- ;------------------------------------------------------------
- PROC doDelayedAniStep NEAR
-
- ASSUME ds:NOTHING,ss:NOTHING
-
- cmp [aniOn],0
- je @@return ; animation not on, return
-
- cmp [aniSpeedCount],0 ; aniSpeedCount is decremented on int8
- jg @@return ; if count>0 return
- mov ax,[aniSpeedDelay]
- mov [aniSpeedCount],ax ; reset count to delay
-
- call aniStepOnceFwd ; do one step of the animation
-
- @@return:
- ret
- ENDP doDelayedAniStep
-
-
- ;------------------------------------------------------------
- ; myTickerInt
- ;
- ; My ticker interrupt, patching int 08h
- ;
- ; does the animating
- ;------------------------------------------------------------
- PROC myTickerInt NEAR
- push bp
- push ax bx cx dx si di ds es
- sti
-
- ASSUME ds:NOTHING,ss:NOTHING
-
- cmp [aniOn],0
- je @@return ; animation not on, return
-
- cmp [aniSpeedCount],0
- je @@return ; if count==0 return
- dec [aniSpeedCount] ; else count--
-
- @@return:
- mov al,20h
- out 20h,al ; end of interrupt
-
- pushf
- call [DWORD cs:startupTickerVec] ; simulate old ticker int
-
- pop es ds di si dx cx bx ax
- pop bp
- iret
- ENDP myTickerInt
-
-
-
- ;------------------------------------------------------------
- ; myMultiplexInt
- ;
- ; My multiplex interrupt, patching int 2fh
- ;
- ;
- ;------------------------------------------------------------
- PROC myMultiplexInt NEAR
- ASSUME ds:nothing
- cmp ah,MultiplexCode
- je @@askingthis
- jmp [cs:startupMultiplexVec] ; not this one, try next
-
- @@askingthis:
- or al,al
- jne @@notfunc0
-
- ; requesting whether is installed
- mov al,0FFh ; indicate that dpAni is already installed
- iret
-
- @@notfunc0:
- cmp al,MPRequestShutdown
- jne @@notshutdown
-
- ; requesting shutdown
-
- ; reset sw ints
- push dx
- push ds ; save regs
-
- ; restore orig MP interrupt intercept
- lds dx,[DWORD cs:startupMultiplexVec] ; ds:dx = original MP int
- mov ax,252fh
- int 21h
-
- ; restore orig Kb interrupt intercept
- lds dx,[DWORD cs:startupKbVec] ; ds:dx = original Kb int
- mov ax,2516h
- int 21h
-
- ; restore orig Ticker interrupt intercept
- lds dx,[DWORD cs:startupTickerVec] ; ds:dx = original Ticker int
- mov ax,2508h
- int 21h
-
- pop ds
- pop dx ; restore regs
-
- mov ax,cs ; ax = para address of this TSR
- iret
-
- @@notshutdown:
-
- iret
- ENDP myMultiplexInt
-
-
- ;* transient portion ****************************************
-
- StartTransient:
-
- presentMessage:
- db 'dpAni is already loaded - cannot install again',0ah,0dh
- db 'Use "dpani /?" for help.',0ah,0dh,'$'
- successMessage:
- db 'dpAni by Carl Chimes 1994 : successfully installed',0ah,0dh
- helpMessage:
- db 'Keys in DeluxePaint IIE:',0ah,0dh
- db ' [F12] to activate (only works once per DP session)',0ah,0dh
- db ' [F11] pause/unpause animation',0ah,0dh
- db ' [GREYENTER] [ALT+KPNUMBER] set first frame nr (starting from 1)',0ah,0dh
- db ' [LEFTALT+GREYENTER] [ALT+KPNUMBER] set nr of frames',0ah,0dh
- db ' [LEFTALT+GREYUP] increase speed',0ah,0dh
- db ' [LEFTALT+GREYDOWN] decrease speed',0ah,0dh
- db ' [LEFTALT+GREYLEFT] single step backwards',0ah,0dh
- db ' [LEFTALT+GREYRIGHT] single step forwards',0ah,0dh
- db ' [LEFTALT+W] [ALT+KPNUMBER] set frame width (default 16)',0ah,0dh
- db ' [LEFTALT+H] [ALT+KPNUMBER] set frame height (default 16)',0ah,0dh
- db ' [LEFTALT+M] toggle multiblock (tessellation) mode',0ah,0dh
- db ' [LEFTALT+1] set Cycle animation type (default)',0ah,0dh
- db ' [LEFTALT+2] set Ramp animation type',0ah,0dh
- db 'Use "dpani" (from DOS) to install',0ah,0dh
- db 'Use "dpani /U" (from DOS) to uninstall',0ah,0dh
- db 'Use "dpani /?" (from DOS) for this help message',0ah,0dh,'$'
-
- sucuninstallMessage:
- db 'dpAni uninstalled',0ah,0dh,'$'
-
- failuninstallMessage:
- db 'dpAni not loaded - cannot uninstall',0ah,0dh,'$'
-
-
- installed db 0 ; whether already installed (0FFh if is)
-
- ;------------------------------------------------------------
- ; InitAndTerminate
- ;
- ; initialises program & terminates (and keeps resident portion
- ; resident).
- ;
- ;------------------------------------------------------------
- PROC InitAndTerminate NEAR
- mov ah,30h
- int 21h
- cmp al,3
- jge @@versionokay
- int 20h ; wrong dos version, exit
- @@versionokay:
-
- mov ax,MultiplexCode SHL 8
- int 2Fh ; al=0FFh -> already installed
- mov [installed],al
-
- cmp [BYTE 80h],3
- jne short @@nocommandline
- cmp [WORD 82h],'u/'
- je short @@deinstall
- cmp [WORD 82h],'U/'
- je short @@deinstall
- cmp [WORD 82h],'?/'
- je short @@help
-
- @@nocommandline:
- cmp [installed],0FFh
- jne @@notinstalled ; everything is okay - want to install
-
- ; already installed and not Uninstalling - print error & exit
- mov dx,OFFSET presentMessage
- mov ah,09h
- int 21h ; display presentMessage
- mov ax,4c01h
- int 21h ; exit error status 1
-
- @@deinstall:
- cmp [installed],0FFh
- jne short @@cantuninstall
-
- ; already installed and want to Uninstall
- mov ax,(MultiplexCode SHL 8) OR MPRequestShutdown
- int 2Fh
- ; now ax has para address of TSR
- mov es,ax
- mov ah,49h
- int 21h ; free mem block (of installed TSR)
- mov dx,OFFSET sucuninstallMessage
- mov ah,09h
- int 21h ; display success uninstall message
- mov ax,4c00h
- int 21h ; exit with status 0
-
- @@cantuninstall:
- ; want to Uninstall but TSR not loaded
- mov dx,OFFSET failuninstallMessage
- mov ah,09h
- int 21h ; display failed uninstall message
- mov ax,4c01h
- int 21h ; exit with status 1
-
- @@help:
- ; want to see help message
- mov dx,OFFSET helpMessage
- mov ah,09h
- int 21h ; display help message
- mov ax,4c00h
- int 21h ; exit with status 0
-
- @@notinstalled:
-
- ; wish to install dpAni
-
- mov es,[2ch]
- mov ah,49h
- int 21h ; free environment block
-
-
- ; initialise keybd int
- mov ax,3516h
- int 21h ; es:bx= keybd int vector
- mov [WORD LOW startupKbVec],bx
- mov [WORD HIGH startupKbVec],es
- mov dx,OFFSET myKbInt
- mov ax,2516h
- int 21h ; setup my keyboard interrupt intercept
-
-
- ; initialise multiplex int
- mov ax,352fh
- int 21h ; es:bx= multiplex int vector
- mov [WORD LOW startupMultiplexVec],bx
- mov [WORD HIGH startupMultiplexVec],es
- mov dx,OFFSET myMultiplexInt
- mov ax,252fh
- int 21h ; setup my keyboard interrupt intercept
-
- ; initialise ticker int
- mov ax,3508h
- int 21h ; es:bx= ticker int vector
- mov [WORD LOW startupTickerVec],bx
- mov [WORD HIGH startupTickerVec],es
- mov dx,OFFSET myTickerInt
- mov ax,2508h
- int 21h ; setup my ticker interrupt intercept
-
- mov dx,OFFSET successMessage
- mov ah,09h
- int 21h ; display successMessage
-
- mov dx,OFFSET StartTransient + 15
- mov cl,4
- shr dx,cl
- mov ax,3100h ; error status 0
- int 21h ; terminate & stay resident (keep up to InitAndTerminate)
- ENDP InitAndTerminate
-
-
-
-
- END ; of program
-